//package com.chengyu.core.utils;
//
//package util;
//
//import java.io.ByteArrayOutputStream;
//import java.io.FileInputStream;
//import java.io.FileNotFoundException;
//import java.io.IOException;
//import java.io.UnsupportedEncodingException;
//import java.math.BigInteger;
//import java.net.URISyntaxException;
//import java.nio.charset.StandardCharsets;
//import java.nio.charset.UnsupportedCharsetException;
//import java.security.GeneralSecurityException;
//import java.security.InvalidKeyException;
//import java.security.MessageDigest;
//import java.security.NoSuchAlgorithmException;
//import java.security.PrivateKey;
//import java.security.Signature;
//import java.security.SignatureException;
//import java.sql.Connection;
//import java.sql.PreparedStatement;
//import java.sql.SQLException;
//import java.util.Base64;
//import java.util.HashMap;
//import java.util.Map;
//
//import org.apache.http.ParseException;
//import org.apache.http.client.methods.CloseableHttpResponse;
//import org.apache.http.client.methods.HttpGet;
//import org.apache.http.client.methods.HttpPost;
//import org.apache.http.client.utils.URIBuilder;
//import org.apache.http.entity.StringEntity;
//import org.apache.http.impl.client.CloseableHttpClient;
//import org.apache.http.util.EntityUtils;
//
//import com.alibaba.fastjson.JSON;
//import com.fasterxml.jackson.core.JsonProcessingException;
//import com.fasterxml.jackson.databind.JsonNode;
//import com.fasterxml.jackson.databind.ObjectMapper;
//import com.fasterxml.jackson.databind.node.ObjectNode;
//import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
//import com.wechat.pay.contrib.apache.httpclient.auth.AutoUpdateCertificatesVerifier;
//import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
//import com.wechat.pay.contrib.apache.httpclient.auth.Verifier;
//import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
//import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator;
//import com.wechat.pay.contrib.apache.httpclient.cert.CertificatesManager;
//import com.wechat.pay.contrib.apache.httpclient.exception.HttpCodeException;
//import com.wechat.pay.contrib.apache.httpclient.exception.NotFoundException;
//import com.wechat.pay.contrib.apache.httpclient.util.AesUtil;
//import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
//
//import cn.hutool.core.util.RandomUtil;
//
//public class WechatPayUtil {
//    public static String createOrder(String openid, String description, int money) {
//        Connection conn = DBUtil.getConnection();
//        try {
//            //唯一的内部订单号（后续支付、关单、查单、退款都跟这个相关）
//            String outTradeNo = stringToMD5(System.currentTimeMillis() + "" + RandomUtil.randomString(32));
////			如果用字符串存储私钥就用这个
////			PrivateKey merchantPrivateKey = PemUtil
////					.loadPrivateKey(new ByteArrayInputStream(PayConstants.PRIVATE_KEY.getBytes("utf-8")));
//            PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(new FileInputStream("私钥文件路径");
//            // 获取证书管理器实例
//            CertificatesManager certificatesManager = CertificatesManager.getInstance();
//            // 向证书管理器增加需要自动更新平台证书的商户信息
//            certificatesManager.putMerchant(PayConstants.MCH_ID,
//                    new WechatPay2Credentials(PayConstants.MCH_ID,
//                            new PrivateKeySigner(PayConstants.MCH_SERIAL_NO, merchantPrivateKey)),
//                    PayConstants.API_V3KEY.getBytes(StandardCharsets.UTF_8));
//
//            CloseableHttpClient httpClient = WechatPayHttpClientBuilder.create()
//                    .withMerchant(PayConstants.MCH_ID, PayConstants.MCH_SERIAL_NO, merchantPrivateKey)
//                    .withValidator(new WechatPay2Validator(certificatesManager.getVerifier(PayConstants.MCH_ID)))
//                    .build();
//
//            HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi");
//            httpPost.addHeader("Accept", "application/json");
//            httpPost.addHeader("Content-type", "application/json; charset=utf-8");
//
//            ByteArrayOutputStream bos = new ByteArrayOutputStream();
//            ObjectMapper objectMapper = new ObjectMapper();
//
//            ObjectNode rootNode = objectMapper.createObjectNode();
//            rootNode.put("mchid", PayConstants.MCH_ID)
//                    .put("appid", PayConstants.APP_ID)
//                    .put("description", description)
//                    .put("notify_url", PayConstants.NOTIFY_URL)
//                    .put("out_trade_no", outTradeNo);
//            rootNode.putObject("amount")
//                    .put("total", money);
//            rootNode.putObject("payer")
//                    .put("openid", openid);
//
//            objectMapper.writeValue(bos, rootNode);
//
//            httpPost.setEntity(new StringEntity(bos.toString("UTF-8"), "UTF-8"));
//            CloseableHttpResponse response = httpClient.execute(httpPost);
//
//            String bodyAsString = EntityUtils.toString(response.getEntity());
//
//            String timestamp = (System.currentTimeMillis() / 1000) + "";
//            String nonce = RandomUtil.randomString(32).toUpperCase();
//            StringBuilder builder = new StringBuilder();
//            builder.append(PayConstants.APP_ID).append("\n");
//            builder.append(timestamp).append("\n");
//            builder.append(nonce).append("\n");
//            JsonNode node = objectMapper.readTree(bodyAsString);
//            builder.append("prepay_id="
//                    + node.get("prepay_id").toString().substring(1, node.get("prepay_id").toString().length() - 1))
//                    .append("\n");
//            String ciphertext = sign(builder.toString().getBytes(StandardCharsets.UTF_8));
//
//            Map<String, String> map = new HashMap<String, String>();
//            map.put("nonceStr", nonce);
//            map.put("package", "prepay_id="
//                    + node.get("prepay_id").toString().substring(1, node.get("prepay_id").toString().length() - 1));
//            map.put("timeStamp", timestamp);
//            map.put("paySign", ciphertext);
//            map.put("signType", "RSA");
//            map.put("outTradeNo", outTradeNo);
//            String json = JSON.toJSONString(map);
//            //小程序前端获取pay就可以使用wx.requestPayment了
//            return "{\"pay\":" + json + "}";
//        } catch (UnsupportedCharsetException | HttpCodeException | NotFoundException | ParseException | IOException
//                | GeneralSecurityException | SQLException e) {
//            e.printStackTrace();
//        }
//        return "创建订单失败";
//    }
//    /*支付通知和退款通知给服务器的回调 请求头验签*/
//    public static boolean signVerify(String serialNumber, String message, String signature) {
//        try {
//            PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(new FileInputStream("私钥文件路径");
//            // 获取证书管理器实例
//            CertificatesManager certificatesManager = CertificatesManager.getInstance();
//            // 向证书管理器增加需要自动更新平台证书的商户信息
//            certificatesManager.putMerchant(PayConstants.MCH_ID,
//                    new WechatPay2Credentials(PayConstants.MCH_ID,
//                            new PrivateKeySigner(PayConstants.MCH_SERIAL_NO, merchantPrivateKey)),
//                    PayConstants.API_V3KEY.getBytes(StandardCharsets.UTF_8));
//            // 从证书管理器中获取verifier
//            Verifier verifier = certificatesManager.getVerifier(PayConstants.MCH_ID);
//            return verifier.verify(serialNumber, message.getBytes(StandardCharsets.UTF_8), signature);
//        } catch (HttpCodeException | NotFoundException | IOException | GeneralSecurityException e) {
//            e.printStackTrace();
//        }
//        return false;
//    }
//    /*支付通知和退款通知给服务器的回调 解密报文*/
//    public static String decryptOrder(String body) {
//        try {
//            AesUtil util = new AesUtil(PayConstants.API_V3KEY.getBytes(StandardCharsets.UTF_8));
//            ObjectMapper objectMapper = new ObjectMapper();
//            JsonNode node = objectMapper.readTree(body);
//            JsonNode resource = node.get("resource");
//            String ciphertext = resource.get("ciphertext").textValue();
//            String associatedData = resource.get("associated_data").textValue();
//            String nonce = resource.get("nonce").textValue();
//            return util.decryptToString(associatedData.getBytes("utf-8"), nonce.getBytes("utf-8"), ciphertext);
//        } catch (JsonProcessingException | UnsupportedEncodingException | GeneralSecurityException e) {
//            e.printStackTrace();
//        }
//        return null;
//    }
//    /*关单*/
//    public static void closeOrder(String outTradeNo) {
//        try {
//            PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(new FileInputStream("私钥文件路径");
//            // 获取证书管理器实例
//            CertificatesManager certificatesManager = CertificatesManager.getInstance();
//            // 向证书管理器增加需要自动更新平台证书的商户信息
//            certificatesManager.putMerchant(PayConstants.MCH_ID,
//                    new WechatPay2Credentials(PayConstants.MCH_ID,
//                            new PrivateKeySigner(PayConstants.MCH_SERIAL_NO, merchantPrivateKey)),
//                    PayConstants.API_V3KEY.getBytes(StandardCharsets.UTF_8));
//
//            CloseableHttpClient httpClient = WechatPayHttpClientBuilder.create()
//                    .withMerchant(PayConstants.MCH_ID, PayConstants.MCH_SERIAL_NO, merchantPrivateKey)
//                    .withValidator(new WechatPay2Validator(certificatesManager.getVerifier(PayConstants.MCH_ID)))
//                    .build();
//
//            HttpPost httpPost = new HttpPost(
//                    "https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/" + outTradeNo + "/close");
//            httpPost.addHeader("Accept", "application/json");
//            httpPost.addHeader("Content-type", "application/json; charset=utf-8");
//
//            ByteArrayOutputStream bos = new ByteArrayOutputStream();
//            ObjectMapper objectMapper = new ObjectMapper();
//
//            ObjectNode rootNode = objectMapper.createObjectNode();
//            rootNode.put("mchid", PayConstants.MCH_ID);
//
//            objectMapper.writeValue(bos, rootNode);
//
//            httpPost.setEntity(new StringEntity(bos.toString("UTF-8"), "UTF-8"));
//            CloseableHttpResponse response = httpClient.execute(httpPost);
//            System.out.println(response.getStatusLine().getStatusCode()); // 状态码204就关单成功，无响应内容
//        } catch (UnsupportedCharsetException | HttpCodeException | NotFoundException | ParseException | IOException
//                | GeneralSecurityException e) {
//            e.printStackTrace();
//        }
//    }
//    /*查单*/
//    public static String queryOrder(String outTradeNo) {
//        try {
//            PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(new FileInputStream("私钥文件路径");
//            // 获取证书管理器实例
//            CertificatesManager certificatesManager = CertificatesManager.getInstance();
//            // 向证书管理器增加需要自动更新平台证书的商户信息
//            certificatesManager.putMerchant(PayConstants.MCH_ID,
//                    new WechatPay2Credentials(PayConstants.MCH_ID,
//                            new PrivateKeySigner(PayConstants.MCH_SERIAL_NO, merchantPrivateKey)),
//                    PayConstants.API_V3KEY.getBytes(StandardCharsets.UTF_8));
//
//            CloseableHttpClient httpClient = WechatPayHttpClientBuilder.create()
//                    .withMerchant(PayConstants.MCH_ID, PayConstants.MCH_SERIAL_NO, merchantPrivateKey)
//                    .withValidator(new WechatPay2Validator(certificatesManager.getVerifier(PayConstants.MCH_ID)))
//                    .build();
//            URIBuilder uriBuilder = new URIBuilder("https://api.mch.weixin.qq.com/v3/pay/transactions/out-trade-no/"
//                    + outTradeNo + "?mchid=" + PayConstants.MCH_ID);
//            HttpGet httpGet = new HttpGet(uriBuilder.build());
//            httpGet.addHeader("Accept", "application/json");
//
//            CloseableHttpResponse response = httpClient.execute(httpGet);
//
//            String bodyAsString = EntityUtils.toString(response.getEntity());
//            System.out.println(bodyAsString);
//        } catch (HttpCodeException | NotFoundException | ParseException | IOException | GeneralSecurityException
//                | URISyntaxException e) {
//            e.printStackTrace();
//        }
//        return null;
//    }
//    /*退款*/
//    public static String createRefundOrder(String outTradeNo, int total, int refund) {
//        try {
//            PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(new FileInputStream("私钥文件路径");
//            // 获取证书管理器实例
//            CertificatesManager certificatesManager = CertificatesManager.getInstance();
//            // 向证书管理器增加需要自动更新平台证书的商户信息
//            certificatesManager.putMerchant(PayConstants.MCH_ID,
//                    new WechatPay2Credentials(PayConstants.MCH_ID,
//                            new PrivateKeySigner(PayConstants.MCH_SERIAL_NO, merchantPrivateKey)),
//                    PayConstants.API_V3KEY.getBytes(StandardCharsets.UTF_8));
//
//            CloseableHttpClient httpClient = WechatPayHttpClientBuilder.create()
//                    .withMerchant(PayConstants.MCH_ID, PayConstants.MCH_SERIAL_NO, merchantPrivateKey)
//                    .withValidator(new WechatPay2Validator(certificatesManager.getVerifier(PayConstants.MCH_ID)))
//                    .build();
//            HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/refund/domestic/refunds");
//            httpPost.addHeader("Accept", "application/json");
//            httpPost.addHeader("Content-type", "application/json; charset=utf-8");
//
//            ByteArrayOutputStream bos = new ByteArrayOutputStream();
//            ObjectMapper objectMapper = new ObjectMapper();
//
//            ObjectNode rootNode = objectMapper.createObjectNode();
//            String outRefundNo = stringToMD5("refund"+outTradeNo);
//            rootNode.put("out_refund_no", outRefundNo)
//                    .put("notify_url", PayConstants.REFUND_NOTIFY_URL)
//                    .put("out_trade_no", outTradeNo);
//            rootNode.putObject("amount")
//                    .put("total", total)
//                    .put("refund", refund)
//                    .put("currency", "CNY");
//            objectMapper.writeValue(bos, rootNode);
//            httpPost.setEntity(new StringEntity(bos.toString("UTF-8"), "UTF-8"));
//            CloseableHttpResponse response = httpClient.execute(httpPost);
//
//            String bodyAsString = EntityUtils.toString(response.getEntity());
//            System.out.println(bodyAsString);
//        } catch (UnsupportedCharsetException | HttpCodeException | NotFoundException | ParseException | IOException
//                | GeneralSecurityException e) {
//            e.printStackTrace();
//        }
//
//        return null;
//    }
//    /*message为appId、timeStamp、nonceStr、package拼接成的字符串 计算得出paySign*/
//    static String sign(byte[] message) {
//        try {
//            PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(new FileInputStream(
//                    PayUtil.class.getClassLoader().getResource("util/apiclient_key.pem").getPath()));
//            Signature sign = Signature.getInstance("SHA256withRSA");
//            sign.initSign(merchantPrivateKey);
//            sign.update(message);
//            return Base64.getEncoder().encodeToString(sign.sign());
//        } catch (InvalidKeyException e) {
//            e.printStackTrace();
//        } catch (FileNotFoundException e) {
//            e.printStackTrace();
//        } catch (NoSuchAlgorithmException e) {
//            e.printStackTrace();
//        } catch (SignatureException e) {
//            e.printStackTrace();
//        }
//        return null;
//    }
//
//    public static String stringToMD5(String plainText) {
//        byte[] secretBytes = null;
//        try {
//            secretBytes = MessageDigest.getInstance("md5").digest(plainText.getBytes());
//        } catch (NoSuchAlgorithmException e) {
//            throw new RuntimeException("Secret Failed");
//        }
//        String md5code = new BigInteger(1, secretBytes).toString(16);
//        for (int i = 0; i < 32 - md5code.length(); i++) {
//            md5code = "0" + md5code;
//        }
//        return md5code;
//    }
//}